from ctypes import *
import time
# import sys
from func_timeout import func_set_timeout
import numpy as np
import struct
import ctypes
import os
# import re




VCI_USBCAN2 = 4
STATUS_OK = 1
class VCI_INIT_CONFIG(Structure):
    _fields_ = [("AccCode", c_uint),
                ("AccMask", c_uint),
                ("Reserved", c_uint),
                ("Filter", c_ubyte),
                ("Timing0", c_ubyte),
                ("Timing1", c_ubyte),
                ("Mode", c_ubyte)
                ]
class VCI_CAN_OBJ(Structure):
    _fields_ = [("ID", c_uint),
                ("TimeStamp", c_uint),
                ("TimeFlag", c_ubyte),
                ("SendType", c_ubyte),
                ("RemoteFlag", c_ubyte),
                ("ExternFlag", c_ubyte),
                ("DataLen", c_ubyte),
                ("Data", c_ubyte*8),
                ("Reserved", c_ubyte*3)
                ]

class VCI_CAN_OBJ_ARRAY(Structure):
    _fields_ = [('SIZE', ctypes.c_uint16), ('STRUCT_ARRAY', ctypes.POINTER(VCI_CAN_OBJ))]
    def __init__(self,num_of_structs):
                                                                 # this bracket is indispensable
        self.STRUCT_ARRAY = ctypes.cast((VCI_CAN_OBJ * num_of_structs)(),ctypes.POINTER(VCI_CAN_OBJ))
        self.SIZE = num_of_structs
        self.ADDR = self.STRUCT_ARRAY[0]


def try_trans_uint(num_str:str):
    if('.' in num_str):#trans ipv4 addr
        if(num_str.count('.')==3):
            num_ls=num_str.split('.')
            try:
                num_temp=0
                for i in num_ls:
                    num_temp=int(i)+num_temp*256
                return num_temp
            except:
                return
    elif(len(num_str)>2):
        if(num_str[:2]=='0x'):#trans hex
            try:
                return int(num_str[2:],16)
            except:
                return
        elif(num_str[:2]=='0b'):#trans bin
            try:
                return int(num_str[2:],2)
            except:
                return
        else:
            try:
                return int(num_str)
            except:
                return
    else:
        try:
            return int(num_str)
        except:
            return

def try_trans_signedHex(num_str:str):
    signed=False
    if(num_str[0]=="-"):
        signed=True
        num_str=num_str[1:]
    if(len(num_str)>2):
        if(num_str[:2]=='0x'):
            try:
                num=int(num_str[2:],16)
            except:
                return
        elif(num_str[:2]=='0b'):
            try:
                num=int(num_str[2:],2)
            except:
                return
        else:
            try:
                num=int(num_str)
            except:
                return
    else:
        try:
            num=int(num_str)
        except:
            return
    if(signed):
        return hex(0x100000000-num)[-8:],-num
    else:
        return hex(num)[2:].rjust(8,'0'),num



def dac8568_init(cmd_code:list=["04","05"]):
    cmd_ls=[]
    for code in cmd_code:
        cmd_ls.append("05"+code+"0007000000")
        cmd_ls.append("05"+code+"000a000000")
        cmd_ls.append("05"+code+"00090a0000")
        # cmd_ls.append("05"+code+"0008000001")
        cmd_ls.append("05"+code+"00040000ff")
        # cmd_ls.append("05"+code+"0005000000")
    return cmd_ls


cols_ls=['k','yellow','r','darkorange',
      'peru','chartreuse','y','cyan',
      'dodgerblue','navy','b','gray',
      'blueviolet','indigo','magenta','pink']


startBias_dict={
    "CSA_VREST4(mV)" :["050400030",572 ],
    "CSA_VREST3(mV)" :["050400031",572 ],
    "CSA_VREST2(mV)" :["050400032",572 ],
    "CSA_VREST1(mV)" :["050400033",572 ],
    "CSA_VREST0(mV)" :["050400034",572 ],
    "ISFBN_IN(mV)"   :["050400035",100 ],
    "VSFBN_IN(mV)"   :["050400036",977 ],
    "CSA_VREF(mV)"   :["050400037",403 ],
    "VCASN(mV)"      :["050500030",554 ],
    "VSFBP_IN(mV)"   :["050500031",860 ],
    "VBIASP_IN(mV)"  :["050500032",899 ],
    "VBIASN_IN(mV)"  :["050500033",1057],
    "ISFBP_IN(mV)"   :["050500034",100 ],
    "IBIASP_IN(mV)"  :["050500035",100 ],
    "IBIASN_IN(mV)"  :["050500036",100 ],
    "VOFF(mV)"       :["050500037",1200],
    "GMCP_THR(mV)"   :["050e00003",1200],
}

#dac电压配置指令生成
#cmd_front:该通道的特定指令（以字符串表示的16进制数）,vol_set:该通道的电压配置（浮点型，单位mV）
#vref:参考电压（浮点型，单位mV）,vol_limit：上限电压（浮点型，单位mV）
def set_vol_mv(cmd_key:str,vol_set:float,vref:float=2500.0,vol_limit=2500):# 单位mV
    vol_set=float(vol_set)
    cmd_front=startBias_dict[cmd_key][0]
    if(vol_set > vol_limit):
        vol_set=vol_limit
        print(f"over limit! set to {vol_limit} mV")
    elif(vol_set < 0):
        vol_set=0
        print(f"can\'t set negitive voltage! set to 0 mV")
    cmd_str=cmd_front+(hex(int(65536*vol_set/vref))[2:]).rjust(4,'0')+'0'
    return cmd_str


startTML_dict={
    'row_start2'           :['01',3   ],
    'col_start2'           :['02',3   ],
    'row_end2'             :['03',348 ],
    'col_end2'             :['04',503 ],
    'row_step2'            :['05',5   ],
    'col_step2'            :['06',5   ],
    'adc_delay'            :['07',14  ],
    'threshold'            :['08',400 ],
    'debugmode'            :['09',0   ],
    'multiple_adc_pix'     :['0a',4   ],
    'shaodian_scan_colnum' :['0b',101 ],
    'shaodian_scan_num'    :['0c',7070],
    'block_pix_num'        :['0d',40  ],
    'shaodian_dout_en'     :['0e',0   ],
    'bakgnd_thr'           :['0f',100 ],
    'rst_load_time'        :['ff',40  ]
# rst_load_time is config update command, must be the last
}


def set_tml(cmd_key,value):
    cmd_front=startTML_dict[cmd_key][0]
    value=try_trans_uint(value)
    
    return '050d'+cmd_front[-2:]+hex(value)[2:].rjust(8,'0')


tml_data_enSet=["050200000000ff","05020000000000"]
mon_data_enSet=["050c00000000ff","050c0000000000"]
shutdownlist=[
    "05020000000000",
    "050c0000000000",
    "05a1a100000000",
    "05040010ffffff",#power down dac8568
    "05050010ffffff",#power down dac8568
    "05075555555555"
]




firmware_state_dic = {
    '00' : '上电未配置',
    '01' : '上电配置完成',
    '02' : '正常运行',
    '03' : '数传状态',
    '04' : '固件更新状态',
    '05' : '预掉电',
    '06' : '高压设置',
    '07' : '取数使能',
    '08' : 'DAC配置'
}

ota_state = {
    "00" : "空闲",
    "07" : "擦除中",
    "0f" : "擦除完成",
    "30" : "写入中",
    "aa" : "写入成功",
    "e0" : "擦除失败",
    "e1" : "写入失败",
}

def sum8_gen(buf:bytes):
    a=sum(struct.unpack(f"{len(buf)}B",buf))
    return a


tele_table_list=[
    "遥测请求计数",
    "CAN正确帧计数",
    "CAN错误帧计数",
    "CAN接收错误计数",
    "CAN发送错误计数",
    "CAN复位计数",
    "CAN复位类型",
    "最近执行指令码",
    "探测器气压(Pa)",
    "探测器温度(℃)",
    "探测器计数率",
    "伽马暴标志位",
    "drift电压(V)",
    "gtop电压(V)",
    "btom电压(V)",
    "高压电源电流",
    "高压状态",
    "载荷内部温度",
    "自检状态",
    "总电源电压",
    "总电源电流",
    "数据写地址指针",
    "数据读地址指针",
    "固件更新状态",
    "数据传输状态",
    "工作状态标志位",
    "固件版本号",
    "载荷时间",
    "累加和校验"
]

startCompress_dict={
    "pixel_thr"  :["00",30   ],
    "frame_thr"  :["01",150 ],
    "mask_en"    :["02",1 ]
}




def set_addrNum(cmd_key,value):
    cmd_front=startCompress_dict[cmd_key][0]
    value=try_trans_uint(value)
    return '0510'+cmd_front[-2:]+hex(value)[2:].rjust(8,'0')



startGAMA_dict={
    "snr_thr"       :["00",20],
    "min_rate/s"      :["01",200],
    "rate_period(s)"   :["02",10],
    "force_trig(s)"    :["ff",0],
}


def set_gamaTrig(cmd_key,value):
    cmd_front=startGAMA_dict[cmd_key][0]
    value=try_trans_uint(value)
    return '0509'+cmd_front[-2:]+hex(value)[2:].rjust(8,'0')


startETH_dict={
    "port_sel"      :["00", 0  ],
    "set_enable"    :["01", 1  ],
    "self_ip"       :["02",'10.112.128.44'],
    "dest_ip"       :["03",'10.112.128.40'],
    "tx_port"       :["04", 30111 ],
    "rx_port"       :["05", 30111 ],
    "subnet_mask"   :["06", '255.255.255.240'],
    "getway_ip"     :["07", '10.112.128.33']
}


def set_eth(cmd_key,value):
    cmd_front=startETH_dict[cmd_key][0]
    value=try_trans_uint(value)
    return '05e0'+cmd_front[-2:]+hex(value)[2:].rjust(8,'0')


hv_module_dic={
    "0560N":[6000,167],
    "0550N":[5000,200]
}


glb_hvModuleType=""
start_hvProtect={
    "hv_safe_voltage(V)"     :["00",2000],
    "Idiv_threshold(adc)"    :["01",2000],
    "time_threshold(ms)"     :["02",100],
    "protect_chance_num"     :["03",3],
    "safe_period(s)"         :["04",10]
}

def set_hvProtect(cmd_key,value,hvModType):
    max_V,max_I=hv_module_dic[hvModType]
    cmd_front=start_hvProtect[cmd_key][0]
    if(cmd_key=="hv_safe_voltage(V)"):
        value=float(value)
        if(value<0):value=2500
        value=int((value/max_V)*4096)
        return '0508'+cmd_front[-2:]+hex(value)[2:].rjust(8,'0')
    elif(cmd_key=="Idiv_threshold(adc)"):
        value=try_trans_uint(value)
        return '0508'+cmd_front[-2:]+hex(value)[2:].rjust(8,'0')
    elif(cmd_key=="time_threshold(ms)"):
        value=float(value)*100_000
        value=int(value)
        return '0508'+cmd_front[-2:]+hex(value)[2:].rjust(8,'0')
    elif(cmd_key=="protect_chance_num"):
        value=try_trans_uint(value)
        return '0508'+cmd_front[-2:]+hex(value)[2:].rjust(8,'0')
    elif(cmd_key=="safe_period(s)"):
        value=float(value)*100_000_000
        value=int(value)
        return '0508'+cmd_front[-2:]+hex(value)[2:].rjust(8,'0')
    print("error")

def hv_state_decode(hv_state:int):
    hv_state=bin(hv_state)[2:].rjust(16,'0')
    hv_ctl_st="error"
    ctl_str=hv_state[2:8]
    if(ctl_str=="000001"):
        hv_ctl_st="start"
    elif(ctl_str=="000010"):
        hv_ctl_st="DaRst"
    elif(ctl_str=="000100"):
        hv_ctl_st="ilde"
    elif(ctl_str=="001000"):
        hv_ctl_st="set_0"
    elif(ctl_str=="010000"):
        hv_ctl_st="close"
    elif(ctl_str=="100000"):
        hv_ctl_st="ex_en"
    return hv_ctl_st+','+hv_state[8:12]+','+hv_state[12:]

def self_cheak_decode(self_check:int):
    link_status="down"
    if(self_check&0b11==0b11):
        link_status="全双工,up"
    elif(self_check&0b11==0b01):
        link_status="半双工,up"
    port_sel="主"
    if(self_check&0b10000==0b10000):
        port_sel="备"
    return port_sel+','+link_status

def udp_flag_decode(udp_flag:int):
    udp_str=str(udp_flag)
    if(udp_flag==0):
        udp_str="未传输"
    elif(udp_flag==0x11):
        udp_str="传输中"
    elif(udp_flag==0xaa):
        udp_str="传输完成"
    elif(udp_flag==0xee):
        udp_str="FINISH错误"
    return udp_str




class cxpd03_can():
    def __init__(self):
        self.canDLL = windll.LoadLibrary('./ControlCAN.dll') # for python x64
        self.can_sate=self.can_start()
        self.hv_module_type="0560N"
        try:
            self.tele_file=open(f"./.log/teleData_{time.strftime("%Y%m%d%H%M%S", time.localtime())}.bin","wb+")
        except:
            os.mkdir("./.log")
            self.tele_file=open(f"./.log/teleData_{time.strftime("%Y%m%d%H%M%S", time.localtime())}.bin","wb+")
    
    def can_start(self):
        # device open
        ret = self.canDLL.VCI_OpenDevice(VCI_USBCAN2, 0, 0)
        if ret != STATUS_OK:
            print('VCI_OpenDevice open ERROR\r\n')
            return False
        # device channel 0 initial
        vci_initconfig = VCI_INIT_CONFIG(0x80000000, 0xFFFFFFFF, 0,0, 0x00, 0x1c, 0)# baud 500k，normal mod
        ret = self.canDLL.VCI_InitCAN(VCI_USBCAN2, 0, 0, byref(vci_initconfig))
        if ret != STATUS_OK:
            print('VCI_InitCAN1 config ERROR\r\n')
            return False
        # CAN channel start
        ret = self.canDLL.VCI_StartCAN(VCI_USBCAN2, 0, 0)
        if ret != STATUS_OK:
            print('VCI_StartCAN1 start ERROR\r\n')
            return False
        print('VCI_StartCAN1 start SUCCESS\r\n')
        return True

    def can_post64(self,cmd_temp:bytes):
        ubyte_array = c_ubyte*8
        if(len(cmd_temp)!=7):
            print(f"can_post64:len error,{len(cmd_temp)}")
            return
        a = ubyte_array(cmd_temp[0],cmd_temp[1],cmd_temp[2],cmd_temp[3],cmd_temp[4],cmd_temp[5],cmd_temp[6],sum8_gen(cmd_temp))
        ubyte_3array = c_ubyte*3
        b = ubyte_3array(0, 0 , 0)
        #ID; TimeStamp; TimeFlag; SendType; RemoteFlag; ExternFlag; DataLen; Data[8]; Reserved[3]
        vci_can_obj = VCI_CAN_OBJ(0x00273803, 0, 0, 0, 0, 1,  8, a, b)
        self.canDLL.VCI_Transmit(VCI_USBCAN2, 0, 0, byref(vci_can_obj), 1)
    
    def time_broadcast(self):
        sum_data=bytes.fromhex("001500ff")
        time_bytes=bytes.fromhex(hex(int(time.time()))[2:].rjust(8,'0'))
        ubyte_array = c_ubyte*8
        a = ubyte_array(sum_data[0],sum_data[1],sum_data[2],sum_data[3],time_bytes[0],time_bytes[1],time_bytes[2],time_bytes[3])
        # a = ubyte_array(0,0x15,0x0,0xff,0x01,0x02,0x03,0x04)
        ubyte_3array = c_ubyte*3
        b = ubyte_3array(0, 0 , 0)
        vci_can_obj = VCI_CAN_OBJ(0x083FE801, 0, 0, 0, 0, 1,  8, a, b)
        self.canDLL.VCI_Transmit(VCI_USBCAN2, 0, 0, byref(vci_can_obj), 1)
        sum_data=sum_data[2:]+time_bytes

        temp=bytes.fromhex("0000000000000000")
        ubyte_array = c_ubyte*8
        sum_data=sum_data+temp
        a = ubyte_array(temp[0],temp[1],temp[2],temp[3],temp[4],temp[5],temp[6],temp[7])
        # a = ubyte_array(0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12)
        ubyte_3array = c_ubyte*3
        b = ubyte_3array(0, 0 , 0)
        #ID; TimeStamp; TimeFlag; SendType; RemoteFlag; ExternFlag; DataLen; Data[8]; Reserved[3]
        vci_can_obj = VCI_CAN_OBJ(0x083FE021, 0, 0, 0, 0, 1,  8, a, b)
        self.canDLL.VCI_Transmit(VCI_USBCAN2, 0, 0, byref(vci_can_obj), 1)
        
        
        temp=bytes.fromhex("00000000000000")
        ubyte_array = c_ubyte*8
        sum_data=sum_data+temp
        a = ubyte_array(temp[0],temp[1],temp[2],temp[3],temp[4],temp[5],temp[6],sum8_gen(sum_data))
        # a = ubyte_array(0x13,0x14,0x15,0x16,0x17,0x18,0x19,0xf9)
        ubyte_3array = c_ubyte*3
        b = ubyte_3array(0, 0 , 0)
        #ID; TimeStamp; TimeFlag; SendType; RemoteFlag; ExternFlag; DataLen; Data[8]; Reserved[3]
        vci_can_obj = VCI_CAN_OBJ(0x083ff041, 0, 0, 0, 0, 1,  8, a, b)
        self.canDLL.VCI_Transmit(VCI_USBCAN2, 0, 0, byref(vci_can_obj), 1)

    def attitude_post(self):
        sum_data=bytes.fromhex("0015007f")
        time_bytes=bytes.fromhex(hex(int(time.time()))[2:].rjust(8,'0'))
        ubyte_array = c_ubyte*8
        a = ubyte_array(sum_data[0],sum_data[1],sum_data[2],sum_data[3],time_bytes[0],time_bytes[1],time_bytes[2],time_bytes[3])
        # a = ubyte_array(0,0x15,0x0,0xff,0x01,0x02,0x03,0x04)
        ubyte_3array = c_ubyte*3
        b = ubyte_3array(0, 0 , 0)
        vci_can_obj = VCI_CAN_OBJ(0x082FE801, 0, 0, 0, 0, 1,  8, a, b)
        self.canDLL.VCI_Transmit(VCI_USBCAN2, 0, 0, byref(vci_can_obj), 1)
        sum_data=sum_data[2:]+time_bytes

        for i in range(11):
            temp=bytes.fromhex("0123456789abcdef")
            ubyte_array = c_ubyte*8
            sum_data=sum_data+temp
            a = ubyte_array(temp[0],temp[1],temp[2],temp[3],temp[4],temp[5],temp[6],temp[7])
            # a = ubyte_array(0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12)
            ubyte_3array = c_ubyte*3
            b = ubyte_3array(0, 0 , 0)
            #ID; TimeStamp; TimeFlag; SendType; RemoteFlag; ExternFlag; DataLen; Data[8]; Reserved[3]
            vci_can_obj = VCI_CAN_OBJ(0x082FE021, 0, 0, 0, 0, 1,  8, a, b)
            self.canDLL.VCI_Transmit(VCI_USBCAN2, 0, 0, byref(vci_can_obj), 1)
        
        
        temp=bytes.fromhex("0a00000000000f")
        ubyte_array = c_ubyte*8
        sum_data=sum_data+temp
        a = ubyte_array(temp[0],temp[1],temp[2],temp[3],temp[4],temp[5],temp[6],sum8_gen(sum_data))
        # a = ubyte_array(0x13,0x14,0x15,0x16,0x17,0x18,0x19,0xf9)
        ubyte_3array = c_ubyte*3
        b = ubyte_3array(0, 0 , 0)
        #ID; TimeStamp; TimeFlag; SendType; RemoteFlag; ExternFlag; DataLen; Data[8]; Reserved[3]
        vci_can_obj = VCI_CAN_OBJ(0x082ff041, 0, 0, 0, 0, 1,  8, a, b)
        self.canDLL.VCI_Transmit(VCI_USBCAN2, 0, 0, byref(vci_can_obj), 1)
    
    def can_post24(self,cmd_temp:bytes):
        ubyte_array = c_ubyte*8
        if(len(cmd_temp)!=2):
            print(f"can_post24:len error,{len(cmd_temp)}")
            return
        zero=bytes.fromhex("00")
        a = ubyte_array(cmd_temp[0],cmd_temp[1],sum8_gen(cmd_temp),zero,zero,zero,zero,zero)
        ubyte_3array = c_ubyte*3
        b = ubyte_3array(0, 0 , 0)
        #ID; TimeStamp; TimeFlag; SendType; RemoteFlag; ExternFlag; DataLen; Data[8]; Reserved[3]
        vci_can_obj = VCI_CAN_OBJ(0x70200, 0, 0, 0, 0, 1,  3, a, b)
        self.canDLL.VCI_Transmit(VCI_USBCAN2, 0, 0, byref(vci_can_obj), 1)

    
    def cxpd_cmd_str(self,cmd_str:str):
        if(len(cmd_str)==14):
            try:
                print(f"send command:{cmd_str}")
                cmd=bytes.fromhex(cmd_str)
                self.can_post64(cmd)
            except:
                print(f"cmd {cmd_str} error!")
        else:print(f"len of cmd is 16, instead of {len(cmd_str)}({cmd_str})")
            

    
    def cxpd_mon_post(self):
        ubyte_array = c_ubyte*8
        a = ubyte_array(0x00,0x11,0x11,0x0,0x0,0x0,0x0,0x0)
        ubyte_3array = c_ubyte*3
        b = ubyte_3array(0, 0 , 0)
        #ID; TimeStamp; TimeFlag; SendType; RemoteFlag; ExternFlag; DataLen; Data[8]; Reserved[3]
        vci_can_obj = VCI_CAN_OBJ(0x10273801, 0, 0, 0, 0, 1,  3, a, b)
        ret = self.canDLL.VCI_Transmit(VCI_USBCAN2, 0, 0, byref(vci_can_obj), 1)
        return time.time()
    
    def cxpd_get_tele(self,time_post,frame_num,timeout:c_uint=0.01) :
        rx_vci_can_obj = VCI_CAN_OBJ_ARRAY(2500)
        resp_temp=bytes()
        num_rx=0
        while num_rx < frame_num:
            if time.time() - time_post < timeout :
                ret = self.canDLL.VCI_Receive(VCI_USBCAN2, 0, 0, byref(rx_vci_can_obj.ADDR), 2500, 0)
                if(ret>0):
                    num_rx+=1
                    resp_temp+=rx_vci_can_obj.STRUCT_ARRAY[0].Data
            else :
                break
        # print(f"resp_len:{len(resp_temp)},num_frame:{num_rx}\nbytes:{resp_temp.hex()}")
        return resp_temp
    
    
    def cxpd03_mon_get(self,debug=False):
        if(debug):
            print("debug mon get")
            return [0]*31
        self.cxpd_mon_post()
        resp_temp=self.cxpd_get_tele(time.time(),8,0.05)
        # data=np.frombuffer(resp_temp,dtype='B')
        # for i in range(int(len(resp_temp)/8)):
        #     print(resp_temp[i*8:i*8+8].hex())
        # softsum_cheak=np.bitwise_and(data[:-1].sum(),0xff)
        # if(softsum_cheak!=data[-1]):
        #     print(f"多帧校验和错误：{softsum_cheak},{data[-1]}")
        #     return False
        if(len(resp_temp)==64):
            self.tele_file.write(resp_temp)
            # resp_temp=bytes.fromhex("000000000720c0010032152ffdb0b700000000096be5e0793e5000005d24875b50d104cc6a960a4b0f7e027900000020000000000000063124083130bc0b9900")
            reps_cnt, right_frame_cnt, error_frame_cnt, brx_error, btx_error, can_rst_cnt, can_rst_type, res_cmd=struct.unpack('!2H6B',resp_temp[10:20])#frame0
            # bme680_gas_p1, bme680_gas_pt, bme680_gas_t0, gmpd_trig_rate=struct.unpack('!4H',resp_temp[8:16])#frame1
            # print(bme680_gas_p1, bme680_gas_pt, bme680_gas_t0, gmpd_trig_rate)
            bme680_gas_press=int.from_bytes(resp_temp[20:23],byteorder='big')
            bme680_gas_temp=int.from_bytes(resp_temp[23:26],byteorder='big')
            # gmpd_trig_rate=int.from_bytes(resp_temp[26],byteorder='big')
            # gama_state=int.from_bytes(resp_temp[27],byteorder='big')
            gmpd_trig_rate, gama_state=struct.unpack('!BB',resp_temp[26:28])
            temp=struct.unpack('!Q',resp_temp[28:36])[0]#frame2
            hv_mon_drift=(temp>>52)&0xfff
            hv_mon_gtopv=(temp>>40)&0xfff
            hv_mon_btomv=(temp>>28)&0xfff
            hv_power_current=(temp>>16)&0xfff
            hv_state=temp&0xffff
            sts_40_temp, self_cheak, powerin_volatge, powerin_current=struct.unpack('!4H',resp_temp[36:44])#frame3
            emmc_argue_wr, emmc_argue_rd=struct.unpack('!2I',resp_temp[44:52])#frame4
            ota_flag, udp_flag, firmware_state, firmware_version, utc_data, sum_cheak = struct.unpack('!3BHIH',resp_temp[52:63])#frame6
            # print(f"byte_len:{byte_len}, data_type:{data_type}, data_code:{data_code}, reps_cnt:{reps_cnt}, right_frame_cnt:{right_frame_cnt}, error_frame_cnt:{error_frame_cnt}, res_cmd:{res_cmd}, gmpd_trig_rate:{gmpd_trig_rate}, hv_mon_voltage:{hv_mon_voltage}, hv_mon_current:{hv_mon_current}, hv_power_voltage:{hv_power_voltage}, hv_power_current:{hv_power_current}, powerin_volatge:{powerin_volatge}, powerin_current:{powerin_current}, sts_40_temp:{sts_40_temp}, seu_err_cnt:{seu_err_cnt}, seu_tmr_err_cnt:{seu_tmr_err_cnt}, seu_rom_err_cnt:{seu_rom_err_cnt}, ota_flag:{ota_flag}, emmc_argue_wr:{emmc_argue_wr}, emmc_argue_rd:{emmc_argue_rd}, udp_flag:{udp_flag}, firmware_state:{firmware_state}, firmware_version:{firmware_version}, utc_data:{utc_data}, cheak_state:{self_cheak}, sum_cheak:{sum_cheak}, bme680_gas_temp:{bme680_gas_temp}, bme680_gas_press:{bme680_gas_press}")
            # print("sum cheak:",sum_cheak,softsum_cheak)
            ls_raw=list([reps_cnt, right_frame_cnt, error_frame_cnt, brx_error, btx_error, can_rst_cnt, can_rst_type, res_cmd,
                    bme680_gas_press, bme680_gas_temp, gmpd_trig_rate, gama_state,
                    hv_mon_drift, hv_mon_gtopv, hv_mon_btomv, hv_power_current, hv_state,
                    sts_40_temp, self_cheak, powerin_volatge, powerin_current,
                    emmc_argue_wr, emmc_argue_rd,
                    ota_flag, udp_flag, firmware_state, firmware_version, utc_data, sum_cheak])
            bme680_gas_press = (bme680_gas_press-1.4e7)/(-92.7)
            bme680_gas_temp = (bme680_gas_temp-6559968)/51797
            sts_40_temp = -45+175*sts_40_temp/65535
            powerin_volatge=powerin_volatge*1.25
            #the input impedance of amplifier is 105k, so multiplied by 1.05 to correct gain
            hv_mon_drift = ((hv_mon_drift-18)/4096)*1.05*(500.08316/0.08316)
            hv_mon_gtopv = ((hv_mon_gtopv-12)/4096)*1.05*(100.08316/0.08316)*(2/1)
            hv_mon_btomv = ((hv_mon_btomv-11)/4096)*1.05*(39.08316/0.08316)
            hv_mon_drift = f"{hv_mon_drift:.1f}"
            hv_mon_gtopv = f"{hv_mon_gtopv:.1f}"
            hv_mon_btomv = f"{hv_mon_btomv:.1f}"
            try:
                firmware_state=hex(firmware_state)[2:].rjust(2,'0')
                firmware_state=firmware_state_dic[firmware_state]
                ota_flag = ota_state[hex(ota_flag)[2:].rjust(2,'0')]
                if(gama_state==0xff):
                    gama_state="gama暴触发"
                else:
                    gama_state="未触发"
            except:
                pass
            udp_flag=udp_flag_decode(udp_flag)
            self_cheak=self_cheak_decode(self_cheak)
            hv_state=hv_state_decode(hv_state)
            gmpd_trig_rate=gmpd_trig_rate
            utc_data=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(utc_data))
            ls_trans=list([reps_cnt, right_frame_cnt, error_frame_cnt, brx_error, btx_error, can_rst_cnt, can_rst_type, res_cmd,
                    bme680_gas_press, bme680_gas_temp, gmpd_trig_rate, gama_state,
                    hv_mon_drift, hv_mon_gtopv, hv_mon_btomv, hv_power_current, hv_state,
                    sts_40_temp, self_cheak, powerin_volatge, powerin_current,
                    emmc_argue_wr, emmc_argue_rd,
                    ota_flag, udp_flag, firmware_state, firmware_version, utc_data, sum_cheak])
            return [ls_trans,ls_raw]#返回处理前后的遥测列表
        elif(len(resp_temp)>8):
            return -1 #有遥测返回，但是接收数量不足，可以发送时间广播和姿态广播
        # print(f"error:only resive {len(resp_temp)} bytes")
        return False


cmd_means_dict={
    "04":"偏置DAC1配置指令",
    "05":"偏置DAC2配置指令",
    "0e":"触发阈值电压配置指令",
    "0d":"协处理初始化配置指令",
    "10":"压缩阈值配置指令",
    "a1":"高压设置指令",
    "08":"高压保护参数配置指令",
    "09":"伽马暴触发参数配置指令",
    "02":"探测器数据开关指令",
    "0c":"监控数据开关指令",
    "07":"掉电提示指令",
    "11":"数据上传文件大小设置指令",
    "06":"数据上传指令",
    "e0":"UDP网络设置指令",
    "fe":"远程固件更新指令",
    "ff":"生成测试数据",
    "a2":"高压监控取数指令"
}